<?php

namespace App\V3\V3_2\Controllers;

use Illuminate\Http\Request;
use App\V3\V3_2\Services\CheckStorageManageService;
use Illuminate\Support\Facades\Validator;
use App\Helper\Utils\TimeUtil;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB;
use App\V3\V3_2\Models\CheckStorageManageModel;
use App\V3\V3_2\Models\StorageManageModel;
use App\V3\V3_2\Models\MaterielTypeModel;
use App\V3\V3_2\Models\SerialNumberModel;
use App\V3\V3_2\Models\CheckSerialNumberModel;

class CheckStorageManageController extends BaseController
{

    //仓库列表
    public function storageList(Request $request){
        //参数验证
        $validator = Validator::make($data = $request->all(), [
            'pageSize' =>'required|integer',//页面大小
            'currentPage' =>'required|integer',//当前页
        ],[
            'pageSize.required' => '参数`pageSize`丢失',
            'pageSize.integer' => '参数`pageSize`仅能为数字',
            'currentPage.required' => '参数`currentPage`丢失',
            'currentPage.integer' => '参数`currentPage`仅能为数字',
        ]);

        //参数错误响应
        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }
        $list = CheckStorageManageService::getStorageList($this->getMainUserId(), $data);
        $this->log('仓库列表', $list);
        return $this->success($list);
    }

    //仓库及商品列表
    public function getStorageGoodsList(Request $request){

          //参数验证
        $validator = Validator::make($data = $request->all(), [
            'pageSize' =>'required|integer|min:1',//页面大小
            'currentPage' =>'required|integer',//当前页
        ],[
            'storage_id.required' => '`仓库id`缺失',
            'storage_id.integer' => '`仓库id`只能为数字',
            'pageSize.required' => '`页面大小`缺失',
            'pageSize.integer' => '`页面大小`只能为数字',
            'pageSize.min' => '`页面大小`默认最小仅能为1',
            'currentPage.required' => '`页面大小`缺失',
            'currentPage.integer' => '`页面大小`只能为数字',
            'currentPage.min' => '`页面大小`默认最小仅能为1',
        ]);

        //参数错误响应
        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }

        $data['main_id'] = $this->getMainUserId();

        $keyword = empty($request->keyword)?'':$request->keyword;
        $condition = [];

        if(!empty($request->materiel_class_id)) {

            $data['materiel_class_id'] = $request->materiel_class_id;
        }

        $typeId = [];
       if(!empty($data['type_id'])) {
            $typeId = array_filter(explode(',', $data['type_id']));
        }
        $list = CheckStorageManageService::getStorageGoodsList($request->storage_id, $data,$keyword,$typeId);
        $this->log('仓库及商品列表', $list);
        return $this->success($list);

    }

     public function addCheckStorageGoods(Request $request){

         //参数验证
         $validator = Validator::make($data = $request->all(), [
             'storage_id' => 'required|numeric',//仓库id
             'sg_type' => [
                 'required',
                 Rule::In([1,2])
             ],//盘点类型1:整仓库;2:商品;
         ],[
             'storage_id.required'=>'仓库主键`id`缺失',
             'storage_id.numeric' =>'仓库主键`id`必须为整数',
             'sg_type.required'   =>'盘点类型，必要参数',
             'sg_type.in'         =>'盘点类型:1、整仓库;2、商品',
         ]);
         //参数错误响应
         if($info = $validator->errors()->first()) {
             return response()->json([
                 'code' => 1,
                 'msg' => $info,
                 'data' => '',
             ]);
         }
         $arr = array();
         $goodsArr = array();
         $check_no  = $this->getMainUserId().TimeUtil::getMillisecond();
         DB::beginTransaction();
         try {
             if(!empty($data['goods_info'])){//普通商品

                 $goodsInfo = json_decode($data['goods_info'],true);

                 foreach ($goodsInfo as $v){
                     $sInfo = StorageManageModel::select('a.in_storage_num','b.is_use_serial','b.materiel_name')
                             ->from('storage_manage as a')
                             ->leftJoin('materiel_type as b','b.id','=','a.type_id')
                             ->where('a.id',$v['storage_manage_id'])
                             ->where('b.id',$v['type_id'])
                             ->where('a.delete_flag',0)
                             ->where('b.delete_flag',0)->first()->toArray();


                     if(!empty($sInfo)){
                           if($sInfo['in_storage_num'] != $v['check_num'] && $sInfo['is_use_serial'] == 1){//开启序列号
                               //普通商品开启序列号处理
                               if(empty($v['serial_no'])){
                                   $this->fail('','物料商品'.$sInfo['materiel_name'].'的序列号不能为空');
                               }

                               $serial_no_array = explode(',',$v['serial_no']);

                               if(count($serial_no_array) > $v['check_num']){
                                   $this->fail('','序列号数量大于了'.$sInfo['materiel_name'].'的数量!只需要'.$v['check_num'].'个序列号');
                               }

                               if(count($serial_no_array) < $v['check_num']){
                                   $this->fail('','序列号数量与'.$sInfo['materiel_name'].'的数量不相等!还差'.$v['check_num']-$serial_no_array.'个序列号');
                               }

                              if(count($serial_no_array) == $v['check_num']){
                               foreach ($serial_no_array as $serial_key => $serial_data) {
                                   //检查序列号是否使用
                                   $serialInfo = SerialNumberModel::where(['goods_id' => $v['type_id'], 'serial_no' => $serial_data])->first();

                                    if(!empty($serialInfo)){
                                        if($serialInfo['status'] === 0){
                                           SerialNumberModel::where([
                                                            'status'    => 0,
                                                            'serial_no' => $serial_data,
                                                            'goods_id'  => $serialInfo['goods_id'],
                                                            ])->update(['status' => SerialNumberModel::UNUSEDSTATUS]);
                                        }else{
                                            $this->fail('','物料商品'.$sInfo['materiel_name'].'的序列号'.$serial_data.'已存在');
                                        }
                                    }else{
                                        SerialNumberModel::insertGetId([
                                                'status'            => 1,
                                                'batch_no'          => "",
                                                'serial_no'         => $serial_data,
                                                'storage_manage_id' => $v['storage_manage_id'],
                                                'goods_id'          => $v['type_id'],
                                                'created_at'        => time(),
                                                'main_id'          => $this->getMainUserId(),
                                                ]);
                                    }
                                }
                          }

                            CheckSerialNumberModel::insertGetId([
                              'status'           => 1,
                              'main_id'          => $this->getMainUserId(),
                              'serial_number'    => $v['serial_no'],
                              'storage_manage_id'=> $v['storage_manage_id'],
                              'type_id'          => $v['type_id'],
                              'product_id'       => "",
                              'goods_flag'       => 1,
                              'check_no'         => $check_no,
                              'created_at'       => time()
                          ]);
                       }
                     }else{
                         $this->fail('','物料商品的'.$sInfo['materiel_name'].'不存在');
                     }

                if(!empty($v['check_num']) && getDecimalPointLeng($v['check_num'])>7) return $this->fail('','盘点数小数点后，不能超过6位数字 。');
                     if(!empty($v['yk_num']) && getDecimalPointLeng($v['yk_num'])>7) return $this->fail('','盈亏数量小数点后，不能超过6位数字。');
                     if(!empty($data['is_cover'])){

                     $v['is_cover']   = $data['is_cover'];
                     }
                     $v['check_time'] = time();
                     $v['created_at'] = time();
                     $v['sg_type']    = $data['sg_type'];
                     $v['user_id']    = $this->getUserId();
                     $v['storage_id'] = $data['storage_id'];
                     $v['main_id']    = $this->getMainUserId();
                     $v['check_no']   = $check_no;
                     $arr[]=[
                         'id'=>$v['storage_manage_id'],
                         'in_storage_num'=>$v['check_num'],
                         'virtual_storage_num'=>$v['check_num']
                     ];
                     unset($v['serial_no']);
                     $goodsArr[] = $v;

                 }
             }
             if(!empty($data['product_info'])){//组件套餐

                 $productInfo = json_decode($data['product_info'],true);
                 foreach ($productInfo as $pv){

                     $pInfo = StorageManageModel::select(
                         'b.is_use_serial',
                         'b.materiel_name',
                         'b.is_product_materiel',
                         'a.in_storage_num'
                         )->from('storage_manage as a')
                         ->leftJoin('materiel_type as b','b.id','=','a.type_id')
                         ->where('a.id',$pv['storage_manage_id'])
                         ->where('b.id',$pv['type_id'])
                         ->where('a.delete_flag',0)
                         ->where('b.delete_flag',0)->first();

                     if(!empty($pInfo)){
                         if($pInfo['is_product_materiel'] != 1){
                             $this->fail('','商品'.$pInfo['materiel_name'].'不是组件套餐');
                         }

                         if($pInfo['in_storage_num'] != $pv['check_num'] && $pInfo['is_use_serial'] == 1){//开启序列号

                             if(!empty($pv['product_content'])){
                                 foreach ($pv['product_content'] as $key=>$value){

                                     $zInfo = MaterielTypeModel::select('b.*','materiel_name')
                                             ->from('materiel_type as a')
                                             ->leftJoin('materiel_product_content as b','b.type_id','=','a.id')
                                             ->where('b.type_id',$value['type_id'])
                                             ->where('a.is_product_materiel',0)
                                             ->where('b.delete_flag',0)->where('a.delete_flag',0)->first()->toArray();

                                      if(empty($zInfo)){
                                        $this->fail('','套餐'.$pInfo['materiel_name'].'的组件'.$zInfo['materiel_name'].'不存在');
                                      }
                                      //套餐组件开启序列号
                                      if(empty($value['serial_no'])){
                                        $this->fail('','套餐'.$pInfo['materiel_name'].'组件'.$zInfo['materiel_name'].'的序列号不能为空');
                                      }

                                       $serial_no_array = explode(',',$value['serial_no']);

                                       if(count($serial_no_array) > $pv['check_num']*$zInfo['num']){
                                           $this->fail('','序列号数量大于了组件'.$zInfo['materiel_name'].'的数量!只需要'.$pv['check_num']*$zInfo['num'].'个序列号');
                                       }

                                       if(count($serial_no_array) < $pv['check_num']*$zInfo['num']){
                                           $this->fail('','序列号数量与组件'.$zInfo['materiel_name'].'的数量不相等!还差'.$pv['check_num']*$zInfo['num']-$serial_no_array.'个序列号');
                                       }

                                       if(count($serial_no_array) == $pv['check_num']*$zInfo['num']){

                                           foreach ($serial_no_array as $serial_key => $serial_data) {
                                               //检查序列号是否使用
                                               $serialInfo = SerialNumberModel::where(['goods_id' => $value['type_id'], 'serial_no' => $serial_data])->first();
                                               if(!empty($serialInfo)){
                                                   if($serialInfo['status'] === 0){
                                                       SerialNumberModel::where([
                                                           'status'    => 0,
                                                           'serial_no' => $serial_data,
                                                           'goods_id'  => $serialInfo['goods_id'],
                                                       ])->update(['status' => 1]);
                                                   }else{
                                                       $this->fail('','套餐'.$pInfo['materiel_name'].'组件'.$zInfo['materiel_name'].'的序列号已存在！状态为1');
                                                   }
                                               }else{
                                                   SerialNumberModel::insertGetId([
                                                       'status'            => 1,
                                                       'batch_no'          => "",
                                                       'serial_no'         => $serial_data,
                                                       'storage_manage_id' => $pv['storage_manage_id'],
                                                       'goods_id'          => $value['type_id'],
                                                       'created_at'        => time(),
                                                       'main_id'          => $this->getMainUserId(),
                                                   ]);
                                               }
                                           }

                                         CheckSerialNumberModel::insertGetId([
                                               'status'           => 1,
                                               'main_id'          => $this->getMainUserId(),
                                               'serial_number'    => $value['serial_no'],
                                               'storage_manage_id'=> $pv['storage_manage_id'],
                                               'type_id'          => $value['type_id'],
                                               'product_id'       => $pv['type_id'],
                                               'goods_flag'       => 2,
                                               'check_no'         => $check_no,
                                               'created_at'       => time()
                                           ]);
                                       }
                                 }
                             }
                         }
                     }else{
                         $this->fail('','套餐'.$pInfo['materiel_name'].'不存在');
                     }

                     if(!empty($pv['check_num']) && getDecimalPointLeng($pv['check_num'])>7) return $this->fail('','套餐'.$pInfo['materiel_name'].'的盘点数小数点后，不能超过6位数字 。');
                     if(!empty($pv['yk_num']) && getDecimalPointLeng($pv['yk_num'])>7) return $this->fail('','套餐'.$pInfo['materiel_name'].'的盈亏数量小数点后，不能超过6位数字。');
                     if(!empty($data['is_cover'])){

                         $pv['is_cover']   = $data['is_cover'];
                     }

                     $pv['check_time'] = time();
                     $pv['created_at'] = time();
                     $pv['sg_type']    = $data['sg_type'];
                     $pv['user_id']    = $this->getUserId();
                     $pv['storage_id'] = $data['storage_id'];
                     $pv['main_id']    = $this->getMainUserId();
                     $pv['check_no']   = $check_no;

                     $arr[] = [
                         'id'                  => $pv['storage_manage_id'],
                         'in_storage_num'      => $pv['check_num'],
                         'virtual_storage_num' => $pv['check_num']
                     ];

                     unset($pv['product_content']);
                     $goodsArr[] = $pv;
                    }
             }
             if(!empty($data['is_cover'])){
                 if(!empty($arr)){
                    batch()->update(new StorageManageModel(),$arr,'id');
                 }
             }
             if(!empty($goodsArr)){
                 CheckStorageManageModel::insert($goodsArr);
             }
             $this->log('新建整库盘点', $data);
             DB::commit();
             return $this->success();
         } catch (\Exception $e) {
             DB::rollBack();
             $this->fail('',$e->getMessage());
         }
    }

    /**
     * 修改仓库和商品盘点数
     * @param check_no 盘点编号
     * @param is_cover 是否开启覆盖库存
     * @param storage_manage_id  库存id
     * @param type_id            物料类型名称/型号id
     * @param yk_flag            物料类型名称/型号id
     * @param check_num  物料类型名称/型号id
     * @param yk_num  物料类型名称/型号id
     */
    public function updCheckStorageGoods(Request $request){
        //参数验证
        $validator = Validator::make($data = $request->all(), [
            'check_no' =>'required|integer',//盘点编号
        ],[
            'check_no.required' => '`盘点编号`必要参数',
            'check_no.integer' => '`盘点编号`只能为数字',
        ]);
        //参数错误响应
        if($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }
        $info = CheckStorageManageModel::select('check_no','storage_id')
                ->where('check_no',$data['check_no'])->first()->toArray();

        if(empty($info)) return $this->fail('','没有找到，要修改的盘点数据。');

        $arr = array();

            if(!empty($data['goods_info'])){

                $goodsInfo = json_decode($data['goods_info'],true);
                DB::beginTransaction();
                try {
                foreach ($goodsInfo as &$v){
                    if(!empty($v['check_num']) && getDecimalPointLeng($v['check_num'])>7) return $this->fail('','盘点数小数点后，不能超过6位。');
                    if(!empty($v['yk_num']) && getDecimalPointLeng($v['yk_num'])>7) return $this->fail('','盈亏数量小数点后，不能超过6位。');
                    if(!empty($data['is_cover'])){

                        $v['is_cover']   = $data['is_cover'];
                    }

                    $v['updated_at'] = time();
                    $condition['type_id']    = $v['type_id'];
                    $condition['check_no']   = $info['check_no'];
                    $condition['storage_id'] = $info['storage_id'];
                    $condition['storage_manage_id'] = $v['storage_manage_id'];
                    CheckStorageManageModel::where($condition)->update($v);

                    $arr[]=[
                        'id'=>$v['storage_manage_id'],
                        'in_storage_num'=>$v['check_num'],
                        'virtual_storage_num'=>$v['check_num']
                    ];
                }

                if(!empty($data['is_cover'])){
                        batch()->update(new StorageManageModel(),$arr,'id');
                }

                $this->log('新建整库盘点', $data);
                DB::commit();
                return $this->success();
            } catch (\Exception $e) {
                DB::rollBack();
                $this->fail('',$e->getMessage());
            }
        }
    }

    /**
     * 通过批次号查询商品信息（扫一扫）
     * @param Request $request
     */
    public function readBatchNo(Request $request)
    {
        //参数验证
        $validator = Validator::make($data = $request->all(), [
            'batch_no' =>'required',//条码信息
            'code_type' => 'required',
        ],[
            'batch_no.required' => '参数`条码信息`缺失',
            'code_type.required' => '参数`码的类型`缺失',
        ]);

        //参数错误响应
        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }
        $this->log('通过序列号查询商品信息', $data);
        $data['batch_title'] = $this->batchTitle();
        $data['main_id'] = $this->getMainUserId();
        return response()->json(
            CheckStorageManageService::readBatchNo($data)
            );
    }
    /**
     * 盘点仓库和商品列表
     * @param Request $request
     */
    public function getCheckList(Request $request){

        //参数验证
        $validator = Validator::make($data = $request->all(), [
            'pageSize' =>'required|integer|min:1',//页面大小
            'currentPage' =>'required|integer',//当前页
        ],[
            'pageSize.required' => '`页面大小`缺失',
            'pageSize.integer' => '`页面大小`只能为数字',
            'pageSize.min' => '`页面大小`默认最小仅能为1',
            'currentPage.required' => '`页面大小`缺失',
            'currentPage.integer' => '`页面大小`只能为数字',
            'currentPage.min' => '`页面大小`默认最小仅能为1',
        ]);

        //参数错误响应
        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }
        $condition['a.main_id'] = $this->getMainUserId();
        $keyword = empty($request->keyword)?'':$request->keyword;
        $list = CheckStorageManageService::checkList($condition,$data,$keyword);
        $this->log('通过批次号查询商品信息', $list);
        return $this->success($list);
    }

    /**
     * 盘点盈亏列表
     * @param Request $request
     */
    public function getCheckYkGoodsList(Request $request){

        //参数验证
        $validator = Validator::make($data = $request->all(), [
            'pageSize' =>'required|integer|min:1',//页面大小
            'currentPage' =>'required|integer',//当前页
            'check_no' =>'required|integer',//盘点编号
          /*   'yk_flag' => [
                'required',
                Rule::In([1,2])
            ],//盘点类型1:整仓库;2:商品; */
        ],[
            'check_no.required' => '`盘点编号`必要参数',
            'check_no.integer' => '`盘点编号`只能为数字',
            'pageSize.required' => '`页面大小`缺失',
            'pageSize.integer' => '`页面大小`只能为数字',
            'pageSize.min' => '`页面大小`默认最小仅能为1',
            'currentPage.required' => '`页面大小`缺失',
            'currentPage.integer' => '`页面大小`只能为数字',
            'currentPage.min' => '`页面大小`默认最小仅能为1',
           /*  'yk_flag.required'         =>'盘点类型，必要参数',
            'yk_flag.in'         =>'盘点类型:1、盈;2、亏', */
        ]);

        //参数错误响应
        if ($info = $validator->errors()->first()) {
            return $this->fail('', $info);
        }
        $condition['a.main_id'] = $this->getMainUserId();
        $keyword = empty($request->keyword)?'':$request->keyword;
        $list = CheckStorageManageService::checkSkGoodsList($condition,$data,$keyword);

        if(!empty($list['data'])){
          foreach ($list['data'] as $k=>$v){
              $list['data'][$k]['shelf_name']    = !empty($v['shelf_name'])?$v['shelf_name']:"";
              $list['data'][$k]['location_name'] = !empty($v['location_name'])?$v['location_name']:"";
              if($v['is_cover'] == 1){
                  if($v['yk_flag'] == 2){
                      $list['data'][$k]['in_storage_num'] =$v['check_num']+$v['yk_num'];
                  }elseif($v['yk_flag'] == 1){
                      $list['data'][$k]['in_storage_num'] =$v['check_num']-$v['yk_num'];
                  }
              }
          }
        }
        $this->log('通过批次号查询商品信息', $list);
        return $this->success($list);
    }
}
